home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / Drivers / ZeusSCSI.lha / ZeusSCSI / PatchZeus.asm < prev    next >
Encoding:
Assembly Source File  |  1993-10-26  |  15.3 KB  |  613 lines

  1. ;    PatchZeus.asm - resident module to patch PPI Zeus SCSI driver
  2. ;
  3. ;    Written by Michael L. Hitch
  4. ;        Montana State University
  5. ;        osymh@msu.oscs.montana.edu
  6. ;
  7.  
  8.     include    "exec/types.i"
  9.     include    "exec/nodes.i"
  10.     include    "exec/memory.i"
  11.     include    "exec/resident.i"
  12.     include    "exec/execbase.i"
  13.     include    "exec/libraries.i"
  14.     include    "exec/io.i"
  15.     include    "exec/errors.i"
  16.     include    "devices/scsidisk.i"
  17.     include    "libraries/configvars.i"
  18.     include    "libraries/expansion.i"
  19.     include    "hardware/cia.i"
  20.     include    "hardware/custom.i"
  21.  
  22. ;    xref    _LVOOpenLibrary
  23. ;    xref    _LVOCloseLibrary
  24. ;    xref    _LVOFindConfigDev
  25.     xref    _LVOAllocSignal
  26.     xref    _LVOFreeSignal
  27.     xref    _LVOFindTask
  28.     xref    _LVOFindName
  29.     xref    _LVOSignal
  30.     xref    _LVOWait
  31.     xref    _LVOAllocMem
  32.     xref    _LVOSumKickData
  33.     xref    _LVOForbid
  34.     xref    _LVOPermit
  35.     xref    _LVODisable
  36.     xref    _LVOEnable
  37.     xref    _LVOSupervisor
  38.     xref    _LVOCacheControl
  39.     xref    _ciaa
  40.     xref    _custom
  41.  
  42.     csect    text
  43. ;
  44. ; Program entry point
  45. ;
  46.     movem.l    d2-d3/a2/a5/a6,-(sp)
  47.     move.l    4,a6
  48. ;
  49. ; *** process command line arguments
  50. ;
  51.     jsr    AddResident(pc)        ; Add program to KickMemPtr list
  52. ;*** check status?
  53. ;
  54.     movem.l    (sp)+,d2-d3/a2/a5/a6
  55.     rts
  56. ;
  57. ;
  58. AddResident
  59.     move.l    KickMemPtr(a6),a0
  60. 1$:
  61.     move.l    a0,d0
  62.     beq.s    NewResident        ; Not found
  63.     move.l    LN_NAME(a0),a1        ; name of this entry
  64.     lea    TagName(pc),a2        ; my name
  65. 2$:
  66.     move.b    (a1)+,d0
  67.     cmp.b    (a2)+,d0
  68.     bne.s    3$
  69.     tst.b    d0
  70.     bne    2$
  71. ; found entry
  72.     moveq    #1,d0
  73.     rts
  74. 3$:
  75.     move.l    (a0),a0            ; Next entry
  76.     bra    1$
  77. ;
  78. ; Layout of memory block
  79. ;    ds.b    8        Overhead space for AllocAbs
  80. ;    ds.b    ML_SIZE        Memory entry list
  81. ;    ds.b    ME_SIZE        Memory entry
  82. ;    ds.b    8        RomTab pointer array
  83. ;    ds.b    nnn        Resident module
  84. ;
  85. KM_RTPTR equ    ML_SIZE+ME_SIZE        ; Location of RomTag pointer array
  86. KM_SIZE    equ    KM_RTPTR+8        ; Size of KickMem info header
  87. ;
  88. NewResident:
  89.     moveq    #KM_SIZE+8,d0        ; size of KickMem header + 8 byte overhead
  90.     add.l    RomTag+6(pc),d0
  91.     sub.l    RomTag+2(pc),d0        ; add length of resident module
  92.     move.l    #MEMF_24BITDMA!MEMF_CLEAR,d1
  93.     jsr    _LVOAllocMem(a6)    ; allocate memory
  94.     tst.l    d0
  95.     bne.s    1$
  96.     moveq    #KM_SIZE+8,d0        ; size of KickMem header + 8 byte overhead
  97.     add.l    RomTag+6(pc),d0
  98.     sub.l    RomTag+2(pc),d0        ; add length of resident module
  99.     move.l    #MEMF_CHIP!MEMF_CLEAR,d1
  100.     jsr    _LVOAllocMem(a6)    ; allocate memory
  101.     tst.l    d0
  102.     bne.s    1$
  103.     moveq    #2,d0
  104.     rts
  105. 1$:
  106.     move.l    d0,a0            ; a0 = address of allocated memory
  107.     lea    8(a0),a2        ; a2 = address of MemList
  108.     move.b    #NT_MEMORY,LN_TYPE(a2)    ; initialize MemList
  109.     move.w    #1,ML_NUMENTRIES(a2)
  110.     move.l    a0,ML_ME(a2)
  111.     moveq    #KM_SIZE+8,d0        ; size of KickMem header + 8 byte overhead
  112.     move.l    d0,ML_ME+ME_LENGTH(a2)
  113.     move.l    RomTag+6(pc),d0
  114.     sub.l    RomTag+2(pc),d0        ; d0 = length of resident module
  115.     add.l    d0,ML_ME+ME_LENGTH(a2)
  116.     lea    KM_SIZE+8(a0),a0    ; point to RomTag structure
  117.     lea    RomTag(pc),a1
  118.     move.l    a0,d1
  119.     sub.l    a1,d1            ; relocation offset for RomTag addresses
  120.     move.l    a0,KM_RTPTR(a2)        ; RomTag Pointer
  121.     subq.l    #1,d0
  122. 2$:    move.b    (a1)+,(a0)+        ; copy resident module
  123.     dbra    d0,2$
  124.     move.l    KM_RTPTR(a2),a0        ; Point to RomTag structure
  125.     add.l    d1,RT_MATCHTAG(a0)    ; relocate absolute addresses
  126.     add.l    d1,RT_ENDSKIP(a0)
  127.     add.l    d1,RT_NAME(a0)
  128.     add.l    d1,RT_IDSTRING(a0)
  129.     add.l    d1,RT_INIT(a0)
  130.     move.l    RT_NAME(a0),LN_NAME(a2)    ; set MemList name same as RomTag name
  131. ;*** add to KickMemPtr & KickTagPtr
  132.     jsr    _LVOForbid(a6)
  133.     lea    KickMemPtr(a6),a0
  134. 3$:    move.l    (a0),d0
  135.     beq.s    4$
  136.     move.l    d0,a0
  137.     bra    3$
  138. 4$:    tst.l    KickMemPtr(a6)
  139.     beq.s    5$
  140.     move.l    a0,LN_PRED(a2)        ; is this really needed?
  141.     move.l    a2,(a0)
  142.     bra.s    6$
  143. 5$:    move.l    a2,KickMemPtr(a6)
  144. 6$:    move.l    KickTagPtr(a6),d0
  145.     beq.s    7$
  146.     bset    #31,d0
  147.     move.l    d0,KM_RTPTR+4(a2)    ; link to existing RomTag pointer array
  148. 7$:    lea    KM_RTPTR(a2),a0        ; address of our RomTag pointer array
  149.     move.l    a0,KickTagPtr(a6)
  150.     jsr    _LVOSumKickData(a6)
  151.     move.l    d0,KickCheckSum(a6)
  152.     jsr    _LVOPermit(a6)
  153. ;*** call resident initialization routine?
  154.     lea    myClearCache(pc),a5    ; clear caches before executing
  155.     jsr    _LVOSupervisor(a6)    ;    the initialization code
  156.     move.l    KM_RTPTR(a2),a0
  157.     move.l    RT_INIT(a0),a0
  158.     jsr    (a0)            ; Call initialization routine
  159.     moveq    #0,d0
  160.     rts
  161. ;
  162. myClearCache:
  163.     cpusha    bc            ; push and invalid both caches
  164.     rte
  165. ;
  166. ;
  167. ; The resident RomTag structure
  168. ;
  169. RomTag:    dc.w    RTC_MATCHWORD
  170.     dc.l    RomTag
  171.     dc.l    EndModule
  172.     dc.b    RTF_COLDSTART
  173.     dc.b    37
  174.     dc.b    NT_KICKMEM
  175.     dc.b    0
  176.     dc.l    TagName
  177.     dc.l    TagID
  178.     dc.l    TagInit
  179.  
  180. TagName: dc.b    "PatchZeus",0
  181.     dc.b    "$VER: "
  182. TagID:    dc.b    "PatchZeus 1.1 (26.10.93)",$0d,$0a,0
  183. ZeusName: dc.b    "PPSscsi2.device",0
  184. ExpName: EXPANSIONNAME
  185.     ds.w    0
  186.  
  187. PATCHLOC1 equ    $19b0            ; setup prior to starting 53C710 script
  188. PATCHLOC2 equ    $1a38            ; wait for 53C710 completion
  189. PATCHLOC3 equ    $1f88            ; Interrupt - signal completion
  190. PATCHLOC4 equ    $1ff8            ; Interrupt - phase mismatch
  191. PATCHLOC5 equ    $20ee            ; 53C170 setup - set SCNTL0
  192. PATCHLOC6 equ    $210c            ; 53C710 setup - set SIEN
  193. PATCHLOC7 equ    $1d32            ; Interrupt - received interrupt
  194. PATCHLOC8 equ    $28ae            ; SCSIcmd - adjust scsi_Actual
  195. PATCHLOC9 equ    $28a0            ; SCSIcmd - adjust scsi_SenseActual
  196. PATCHLOC10 equ    $0ef0            ; Compare partition name with BSTR name
  197. PATCHLOC11 equ    $1ec0            ; Interrupt - code $ff01
  198. PATCHLOC12 equ    $136c            ; Device Open - return HFERR_NoBoard
  199. PATCHLOC13 equ    $27fc            ; ScsiCmd - return HFERR_BadStatus
  200. PATCHLOC14 equ    $1b5a            ; Sync request period
  201.  
  202. ;
  203. ; Entry when resident module is initialized
  204. ;
  205. TagInit:
  206.     movem.l    d2/d3/a2/a4,-(sp)
  207.     lea    _custom,a0            ; Address of custom chip
  208.     move.w    potinp(a0),d0            ; Read register
  209.     ori.w    #$0c00,d0            ; Set output, data = 1
  210.     move.w    d0,potgo(a0)
  211.     move.w    potinp(a0),d0            ; Read data
  212.     andi.w    #$0400,d0            ; Test if Mouse right button pressed
  213.     beq.s    SkipMouse            ; Yes, don't check left button
  214.     lea    _ciaa,a0
  215.     btst    #6,ciapra(a0)            ; Test if Mouse left button pressed
  216.     beq.s    TagExit                ; Yes, skip it
  217. SkipMouse:
  218.     btst    #AFB_68040,AttnFlags+1(a6)    ; is it 68040?
  219.     bne.s    Is_68040
  220.     cmp.w    #36,LIB_VERSION(a6)        ; if version 2.0 or later
  221.     bge.s    TagExit                ; then AFB_68040 is valid
  222. ; *** 68040 not detected on WB1.3
  223.     moveq    #AFF_68030!AFF_68020,d0
  224.     and.w    AttnFlags(a6),d0        ; Kludge for WB1.3
  225.     bne.s    Is_68040
  226. TagExit:
  227.     moveq    #0,d0
  228.     movem.l    (sp)+,d2/d3/a2/a4
  229.     rts
  230.  
  231. Is_68040:
  232.     lea    DeviceList(a6),a0        ; get address of device list
  233.     lea    ZeusName(pc),a1            ; Device driver name
  234.     jsr    _LVOFindName(a6)        ; Find device driver
  235.     tst.l    d0
  236.     beq    TagExit                ; Didn't find it
  237.     move.l    d0,a2
  238. ;
  239. ; Found device driver;  make sure it's the correct version and validate
  240. ;    the places we are going to patch
  241. ;
  242.     bra.s    debug1            ; ** DEBUG ** nop to enable color changes
  243.     move.w    #$00ff,$00dff180    ; ** DEBUG ** set screen color = cyan
  244.     move.l    #$00800000,d0
  245. delay1:    subq.l    #1,d0
  246.     bgt    delay1
  247.     move.w    #$0888,$00dff180
  248. debug1:
  249.     cmp.w    #98,LIB_REVISION(a2)        ; Check if revision 98
  250.     bne    TagExit                ; Nope, skip it
  251.     move.l    LN_NAME(a2),a4
  252.     lea    -$521(a4),a4            ; Base relative to start of ROM
  253.     cmp.l    #$584f206d,PATCHLOC1(a4)    ; verify patch points
  254.     bne    TagExit
  255.     cmp.l    #$206d0008,PATCHLOC2(a4)
  256.     bne    TagExit
  257.     cmp.l    #$217c0000,PATCHLOC3(a4)
  258.     bne    TagExit
  259.     cmp.l    #$02800000,PATCHLOC4(a4)
  260.     bne    TagExit
  261.     cmp.l    #$117c00cc,PATCHLOC5(a4)
  262.     bne    TagExit
  263.     cmp.l    #$10bc00bf,PATCHLOC6(a4)
  264.     bne    TagExit
  265.     cmp.l    #$02800000,PATCHLOC7(a4)
  266.     bne    TagExit
  267.     cmp.l    #$23680004,PATCHLOC8(a4)
  268.     bne    TagExit
  269.     cmp.l    #$3368001a,PATCHLOC9(a4)
  270.     bne    TagExit
  271.     cmp.l    #$e5802b40,PATCHLOC10(a4)
  272.     bne    TagExit
  273.     cmp.l    #$20280030,PATCHLOC11(a4)
  274.     bne    TagExit
  275.     cmp.l    #$0cad0000,PATCHLOC12(a4)
  276.     bne    TagExit
  277.     cmp.l    #$2b7c0000,PATCHLOC13(a4)
  278.     bne    TagExit
  279.     cmp.l    #$001e0104,PATCHLOC14(a4)
  280.     bne    TagExit
  281.     bra.s    debug2            ; ** DEBUG ** nop to enable color changes
  282.     move.w    #$0f0f,$00dff180    ; ** DEBUG ** set screen color = magenta
  283.     move.l    #$00800000,d0
  284. delay2:    subq.l    #1,d0
  285.     bgt    delay2
  286.     move.w    #$0888,$00dff180
  287. debug2:
  288. ;
  289. ; install patches
  290. ;
  291. ; relocate jumps back into the driver
  292. ;
  293.     move.l    a4,d0
  294.     lea    Patch1end(pc),a0
  295.     move.l    (a0),-(a0)
  296.     add.l    d0,(a0)
  297.     lea    Patch2end(pc),a0
  298.     move.l    (a0),-(a0)
  299.     add.l    d0,(a0)
  300.     lea    Patch3end(pc),a0
  301.     move.l    (a0),-(a0)
  302.     add.l    d0,(a0)
  303.     lea    Patch4end(pc),a0
  304.     move.l    (a0),-(a0)
  305.     add.l    d0,(a0)
  306.     lea    Patch7end(pc),a0
  307.     move.l    (a0),-(a0)
  308.     add.l    d0,(a0)
  309.     lea    Patch8end(pc),a0
  310.     move.l    (a0),-(a0)
  311.     add.l    d0,(a0)
  312.     lea    Patch9end(pc),a0
  313.     move.l    (a0),-(a0)
  314.     add.l    d0,(a0)
  315.     lea    Patch10end(pc),a0
  316.     move.l    (a0),-(a0)
  317.     add.l    d0,(a0)
  318.     lea    Patch11end(pc),a0
  319.     move.l    (a0),-(a0)
  320.     add.l    d0,(a0)
  321.     lea    Patch11end2(pc),a0
  322.     move.l    (a0),-(a0)
  323.     add.l    d0,(a0)
  324.     lea    Patch12end(pc),a0
  325.     move.l    (a0),-(a0)
  326.     add.l    d0,(a0)
  327.     lea    Patch12end2(pc),a0
  328.     move.l    (a0),-(a0)
  329.     add.l    d0,(a0)
  330. ;
  331. ; patch new code into the driver
  332. ;
  333.     lea    Patch1(pc),a0        ; setup prior to starting 53C710 script
  334.     move.w    #$4ef9,PATCHLOC1(a4)
  335.     move.l    a0,PATCHLOC1+2(a4)
  336.     lea    Patch2(pc),a0
  337.     move.w    #$4ef9,PATCHLOC2(a4)    ; wait for 53C710 completion
  338.     move.l    a0,PATCHLOC2+2(a4)
  339.     lea    Patch3(pc),a0
  340.     move.w    #$4ef9,PATCHLOC3(a4)    ; Interrupt - signal waiting task
  341.     move.l    a0,PATCHLOC3+2(a4)
  342.     lea    Patch4(pc),a0
  343.     move.w    #$4ef9,PATCHLOC4(a4)    ; Interrupt - phase mismatch
  344.     move.l    a0,PATCHLOC4+2(a4)
  345. ;    move.w    #$00c4,PATCHLOC5+2(a4)        ; don't check parity
  346. ;    move.w    #$00be,PATCHLOC6+2(a4)        ; don't interrupt on parity
  347. ;    move.b    #$c4,$e94003
  348. ;    move.b    #$be,$e94000
  349.     lea    Patch7(pc),a0        ; Interrupt - save 52C710 info for debug
  350.     move.w    #$4ef9,PATCHLOC7(a4)
  351.     move.l    a0,PATCHLOC7+2(a4)
  352.     lea    Patch8(pc),a0        ; SCSIcmd - adjust scsi_Actual
  353.     move.w    #$4ef9,PATCHLOC8(a4)
  354.     move.l    a0,PATCHLOC8+2(a4)
  355.     lea    Patch9(pc),a0        ; SCSIcmd - adjust scsi_SenseActual
  356.     move.w    #$4ef9,PATCHLOC9(a4)
  357.     move.l    a0,PATCHLOC9+2(a4)
  358.     lea    Patch10(pc),a0        ; Compare partition name with BSTR name
  359.     move.w    #$4ef9,PATCHLOC10(a4)
  360.     move.l    a0,PATCHLOC10+2(a4)
  361.     lea    Patch11(pc),a0        ; Interrupt - code $ff01
  362.     move.w    #$4ef9,PATCHLOC11(a4)
  363.     move.l    a0,PATCHLOC11+2(a4)
  364.     lea    Patch12(pc),a0        ; Return HFERR_NoBoard on device open
  365.     move.w    #$4ef9,PATCHLOC12(a4)
  366.     move.l    a0,PATCHLOC12+2(a4)
  367.     move.w    #HFERR_BadStatus,PATCHLOC13+4(a4) ; SCSIcmd - return HFERR_BadSTatus
  368.     move.w    #100/4,PATCHLOC14(a4)        ; negotiate for 100usec period
  369.     lea    510(a2),a0            ; Initialize unused command
  370.     lea    Cmd_Invalid(pc),a1        ; entries in dispatch vector
  371.     moveq    #31,d0
  372. 1$:    tst.l    (a0)
  373.     bne.s    2$                ; this entry defined
  374.     move.l    a1,(a0)
  375. 2$:    addq.l    #4,a0
  376.     dbra    d0,1$
  377. ; to do:  patch new command routines
  378.     move.w    #9850,LIB_REVISION(a2)        ; Change revision to 985x
  379.     moveq    #1,d0
  380.     movem.l    (sp)+,d2/d3/a2/a4
  381.     rts
  382.  
  383. ;
  384. ; Prior to starting 53C710 script execution, initialize task pointer and
  385. ;    allocate a signal
  386. ; Also, turn off data cache if buffer does not start and stop on a quadword
  387. ;    boundary
  388. ;
  389. Patch1:
  390.     addq.w    #4,sp            ; restore stack
  391.     move.l    -8(a5),a0        ; Unit pointer
  392.     move.l    468+20(a0),d0        ;  data length
  393.     add.l    468+24(a0),d0        ;  + data start -> buffer end
  394.     or.l    468+24(a0),d0        ;  | data start
  395.     and.l    #15,d0            ; Flag if buffer not quadword boundary
  396.     move.l    d0,-(sp)        ; save flag
  397.     move.l    d0,-(sp)        ; save old cache settings
  398.     move.l    a6,-(sp)
  399.     move.l    4,a6
  400.     tst.l    d0            ; test flag
  401.     beq.s    1$            ; buffer starts and stops on quadword boundary
  402.     moveq    #0,d0            ; Turn off data cache
  403.     move.l    #CACRF_EnableD,d1
  404.     jsr    _LVOCacheControl(a6)
  405.     move.l    d0,4(sp)        ; save previous cache settings
  406. 1$:
  407.     sub.l    a1,a1
  408.     jsr    _LVOFindTask(a6)    ; get our task pointer
  409.     move.l    8(a5),a0        ; device pointer
  410.     move.l    d0,92(a0)        ; save task pointer
  411.     moveq    #-1,d0
  412.     jsr    _LVOAllocSignal(a6)    ; allocate available signal
  413.     move.l    (sp)+,a6
  414.     move.l    8(a5),a0
  415.     move.l    d0,96(a0)        ; save signal number
  416.     clr.l    100(a0)            ; clear DBC
  417.     move.l    12(a5),a1        ; ***** Debug: get IOR pointer
  418.     move.l    IO_UNIT(a1),34(a0)    ; ***** Debug: save last unit pointer
  419.     jmp    $800019b6
  420. Patch1end:
  421.     dc.l    $000019b6
  422.  
  423. ;
  424. ; Wait for signal from interrupt server and free signal
  425. ;
  426. Patch2:
  427.     move.l    8(a5),a0
  428.     move.l    96(a0),d1        ; get signal number
  429.     moveq    #1,d0
  430.     lsl.l    d1,d0            ; form mask
  431.     move.l    a6,-(sp)
  432.     move.l    4,a6
  433.     jsr    _LVOWait(a6)        ; Wait for signal
  434.     move.l    8(a5),a0
  435.     move.l    96(a0),d0
  436.     jsr    _LVOFreeSignal(a6)    ; free the signal
  437.     move.l    (sp)+,a6
  438.     move.l    (sp)+,d0        ; get previous cache settings
  439.     move.l    (sp)+,d1        ; get flag
  440.     beq.s    1$            ; if data cache was turned off,
  441.     move.l    #CACRF_EnableD,d1
  442.     move.l    a6,-(sp)
  443.     move.l    4,a6
  444.     jsr    _LVOCacheControl(a6)    ; restore previous cache settings
  445.     move.l    (sp)+,a6
  446. 1$:
  447.     jmp    $80001a46
  448. Patch2end:
  449.     dc.l    $00001a46
  450.  
  451. ;
  452. ; When 53C710 has completed, signal waiting task (if any)
  453. ;
  454. Patch3:
  455.     move.l    #1,84(a0)        ; set flag [redundant now]
  456.     move.l    92(a0),d0
  457.     beq.s    1$            ; skip if no task pointer
  458.     move.l    d0,a1
  459.     move.l    96(a0),d1
  460.     moveq    #1,d0
  461.     lsl.l    d1,d0            ; form signal number
  462.     move.l    a6,-(sp)
  463.     move.l    4,a6
  464.     jsr    _LVOSignal(a6)        ; signal the waiting task
  465.     move.l    (sp)+,a6
  466. 1$:
  467.     jmp    $80001f90
  468. Patch3end:
  469.     dc.l    $00001f90
  470.  
  471. ;
  472. ; Phase mismatch, store SBCL register in circular buffer
  473. ; Also, if phase == STATUS, save DBC for adjustment of data transfer length
  474. ;
  475. Patch4:
  476.     move.l    8(a5),a0        ; Device pointer
  477.     moveq    #0,d1
  478.     move.b    43(a0),d1        ; buffer index
  479.     move.b    d0,44(a0,d1)        ; store SBCL value
  480.     addq.w    #1,d1            ; increment index
  481.     andi.w    #$000f,d1        ; wrap around
  482.     move.b    d1,43(a0)
  483.     moveq    #7,d1
  484.     and.l    d1,d0            ; mask phase bits
  485.     cmpi.b    #3,d0            ; is phase STATUS?
  486.     bne.s    1$
  487. ;    move.l    104(a0),100(a0)        ; isolate DBC
  488.     move.l    $e94024,100(a0)        ; get dcmd/dbc */
  489.     clr.b    100(a0)
  490. 1$:
  491.     jmp    $80002088
  492. Patch4end:
  493.     dc.l    $00002088
  494.  
  495. ;
  496. ;  Debug stuff - save DSTAT & SSTAT0 in circular buffer on interrupt
  497. ;         also save DCMD/DBC and DSP
  498. ;
  499. Patch7:
  500.     andi.l    #$ff,d0            ; replaced instruction
  501.     move.b    d0,-14(a5)        ; store DSTAT
  502.     move.l    -4(a5),a0        ; load Device pointer
  503.     moveq    #0,d1
  504.     move.b    42(a0),d1        ; buffer index
  505.     move.b    d0,60(a0,d1)        ; store DSTAT in buffer
  506.     move.b    -19(a5),61(a0,d1)    ; store SSTAT0 in buffer
  507.     addq.w    #2,d1
  508.     andi.w    #15,d1
  509.     move.b    d1,42(a0)        ; update buffer index
  510.     move.l    $e94024,104(a0)        ; save DCMD/DBC
  511.     move.l    $e9402c,108(a0)        ; save DSP
  512.     jmp    $80001d3c
  513. Patch7end:
  514.     dc.l    $00001d3c
  515.  
  516. ;
  517. ; SCSI_cmd - set scsi_Actual correctly
  518. ;
  519. Patch8:
  520.     move.l    4(a0),8(a1)        ; scsi_Actual = scsi_Length
  521.     move.l    -12(a5),a0        ; Unit pointer
  522.     move.l    2066(a0),a0        ; Device pointer
  523.     move.l    100(a0),d0        ; get DBC
  524.     sub.l    d0,8(a1)        ; adjust scsi_Actual
  525.     jmp    $800028b4
  526. Patch8end:
  527.     dc.l    $000028b4
  528.  
  529. ;
  530. ; SCSI_cmd - set scsi_Sense_Actual correctly
  531. ;
  532. Patch9:
  533.     move.w    26(a1),28(a0)        ; scsi_SenseActual = scsi_SenseLength
  534.     move.l    -12(a5),a1        ; Unit pointer
  535.     move.l    2066(a1),a1        ; Device pointer
  536.     move.l    100(a1),d0        ; get DBC
  537.     sub.w    d0,28(a0)        ; adjust scsi_Actual
  538.     move.l    4(a0),100(a1)        ; set DBC = scsi_Length so scsi_Actual
  539.     jmp    $800028a6        ;    will get set to zero
  540. Patch9end:
  541.     dc.l    $000028a6
  542.  
  543. ;
  544. ; Compare RDB name to Device Node BSTR name
  545. ;
  546. Patch10:
  547.     asl.l    #2,d0            ; convert BSTR pointer to address
  548.     addq.l    #1,d0            ; skip count byte
  549.     move.l    d0,-16(a5)
  550.     jmp    $80000ef6
  551. Patch10end:
  552.     dc.l    $00000ef6
  553.  
  554. ;
  555. ; Interrupt code $ff01 - Phase not MsgOut after selection
  556. ;
  557. Patch11:
  558.     move.l    48(a0),d0        ; load DSPS
  559.     cmpi.l    #$0000ff01,d0        ; is it Phase not MsgOut after selection?
  560.     beq.s    Patch11b        ; yes, check current phase
  561. Patch11a:
  562.     jmp    $80001f0c        ; continue
  563. Patch11end:
  564.     dc.l    $00001f0c
  565. Patch11b:
  566.     move.b    8(a0),d1        ; get SBCL
  567.     andi.b    #$07,d1            ; mask off phase
  568.     cmpi.b    #$02,d1            ; is it Command Out?
  569.     bne.s    Patch11a        ; no, continue
  570. ;    andi.b    #$f7,4(a0)        ; <reset ATN?>
  571.     lea    -32602(a4),a1        ; restart script processing for command out
  572.     move.l    a1,44(a0)        ; DSPS
  573.     clr.b    -18(a5)            ; clear flag to signal completion
  574.     jmp    $80001f24        ; (we aren't done yet)
  575. Patch11end2:
  576.     dc.l    $00001f24
  577.  
  578. ;
  579. ; Device Open - return HFERR_NoBoard if unit number >= 100
  580. ;
  581. Patch12:
  582.     move.l    -16(a5),d0        ; get unit number
  583.     cmpi.l    #8,d0
  584.     bhs.s    Patch12a        ; it's not valid
  585.     jmp    $80001386
  586. Patch12end:
  587.     dc.l    $00001386
  588. Patch12a:
  589.     moveq    #HFERR_NoBoard,d1    ; return error
  590.     cmpi.l    #100,d0
  591.     bhs.s    Patch12b
  592.     moveq    #IOERR_OPENFAIL,d1
  593. Patch12b:
  594.     move.l    -8(a5),a0
  595.     move.b    d1,IO_ERROR(a0)
  596.     jmp    $80001450
  597. Patch12end2:
  598.     dc.l    $00001450
  599.  
  600. ;
  601. ; Invalid commands - return error code
  602. ;
  603. Cmd_Invalid:
  604.     move.l    4(sp),a0        ; Get IOR pointer
  605.     moveq    #IOERR_NOCMD,d0        ; set error code
  606.     move.b    d0,IO_ERROR(a0)
  607.     clr.l    IO_ACTUAL(a0)        ; clear io_Actual
  608.     rts
  609.  
  610. EndModule:
  611.  
  612.     end
  613.